<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>WebShell</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/xterm@4.18.0/css/xterm.css" />
    <script src="https://cdn.jsdelivr.net/npm/xterm@4.18.0/lib/xterm.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/xterm-addon-fit@0.5.0/lib/xterm-addon-fit.min.js"></script>
    <style>
        body {
            margin: 0;
            padding: 0;
            background-color: #000;
            height: 100vh;
            display: flex;
            flex-direction: column;
        }
        #terminal {
            flex: 1;
            padding: 10px;
        }
        #header {
            background-color: #333;
            color: white;
            padding: 10px;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }
        #controls {
            display: flex;
            gap: 10px;
        }
        button {
            background-color: #555;
            color: white;
            border: none;
            padding: 5px 10px;
            cursor: pointer;
        }
        button:hover {
            background-color: #777;
        }
    </style>
</head>
<body>
    <div id="header">
        <div>WebShell</div>
        <div id="controls">
            <button id="connectBtn">连接</button>
            <button id="disconnectBtn">断开</button>
            <button id="clearBtn">清屏</button>
        </div>
    </div>
    <div id="terminal"></div>

    <script>
        // 初始化xterm.js
        const term = new Terminal({
            cursorBlink: true,
            theme: {
                background: '#000',
                foreground: '#fff'
            }
        });
        
        const fitAddon = new FitAddon.FitAddon();
        term.loadAddon(fitAddon);
        
        term.open(document.getElementById('terminal'));
        fitAddon.fit();
        
        // WebSocket连接
        let websocket = null;
        let lastCols = term.cols;
        let lastRows = term.rows;
        
        // 连接到WebSocket服务器
        function connect() {
            if (websocket && websocket.readyState === WebSocket.OPEN) {
                term.write('\r\n已经连接到服务器\r\n');
                return;
            }
            
            const protocol = window.location.protocol === 'https:' ? 'wss://' : 'ws://';
            const wsUrl = protocol + window.location.host + '/ws/shell?target=127.0.0.1:22222';
            
            try {
                websocket = new WebSocket(wsUrl);
                
                websocket.onopen = function(event) {
                    term.write('\r\n已连接到WebShell服务器\r\n');
                    // 连接后发送初始终端大小
                    sendTerminalSize();
                };
                
                websocket.onmessage = function(event) {
                    if (event.data instanceof ArrayBuffer) {
                        // 处理二进制数据
                        const bytearray = new Uint8Array(event.data);
                        const decoder = new TextDecoder('utf-8');
                        const text = decoder.decode(bytearray);
                        term.write(text);
                    } else if (typeof event.data === 'string') {
                        term.write(event.data);
                    } else {
                        // 处理Blob类型
                        const reader = new FileReader();
                        reader.onload = function() {
                            term.write(reader.result);
                        };
                        reader.readAsText(event.data);
                    }
                };
                
                websocket.onclose = function(event) {
                    term.write('\r\n连接已断开\r\n');
                };
                
                websocket.onerror = function(error) {
                    term.write('\r\n连接错误: ' + error.message + '\r\n');
                };
            } catch (e) {
                term.write('\r\n连接失败: ' + e.message + '\r\n');
            }
        }
        
        // 断开连接
        function disconnect() {
            if (websocket) {
                websocket.close();
                websocket = null;
            }
        }
        
        // 清屏
        function clear() {
            term.clear();
        }
        
        // 发送数据到WebSocket服务器
        function send(data) {
            if (websocket && websocket.readyState === WebSocket.OPEN) {
                websocket.send(data);
            } else {
                term.write('\r\n未连接到服务器\r\n');
            }
        }
        
        // 发送终端大小信息
        function sendTerminalSize() {
            if (websocket && websocket.readyState === WebSocket.OPEN) {
                const cols = term.cols;
                const rows = term.rows;
                
                // 只有在大小真正改变时才发送
                if (cols !== lastCols || rows !== lastRows) {
                    lastCols = cols;
                    lastRows = rows;
                    
                    // 发送stty命令更新终端大小
                    const sttyCommand = `stty cols ${cols} rows ${rows}\n`;
                    websocket.send(sttyCommand);
                }
            }
        }
        
        // 处理终端输入
        term.onData((data) => {
            send(data);
        });
        
        // 绑定按钮事件
        document.getElementById('connectBtn').addEventListener('click', connect);
        document.getElementById('disconnectBtn').addEventListener('click', disconnect);
        document.getElementById('clearBtn').addEventListener('click', clear);
        
        // 自动连接
        window.addEventListener('load', () => {
            connect();
        });
        
        // 窗口大小调整时适应终端并发送大小更新
        window.addEventListener('resize', () => {
            fitAddon.fit();
            sendTerminalSize();
        });
    </script>
</body>
</html>
